package com.edooschool.oral.arithmetic.processor.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;

import com.demo2do.core.entity.exception.BusinessException;
import com.demo2do.core.entity.result.HttpResult;
import com.demo2do.core.http.annotation.Rao;
import com.demo2do.core.utils.JsonUtils;
import com.demo2do.core.utils.StringUtils;
import com.demo2do.core.wechat.Wechat;
import com.demo2do.core.wechat.entity.auth.WebAuthLogin;
import com.demo2do.core.wechat.entity.cfg.JsConfig;
import com.demo2do.core.wechat.entity.token.JsTicket;
import com.demo2do.core.wechat.entity.token.Token;
import com.edooschool.oral.arithmetic.CacheKeys;
import com.edooschool.oral.arithmetic.processor.WechatProcessor;
import com.edooschool.oral.arithmetic.rao.WechatRao;

/**
 * 
 * @author mohanlan
 *
 */
@Component("wechatProcessor")
public class WechatProcessorImpl implements WechatProcessor {
    
    private static final Logger logger = LoggerFactory.getLogger(WechatProcessorImpl.class);
    
    @Value("#{config['tencent.host']}")
    private String host;
    
    @Rao
    private WechatRao wechatRao;
    
    /*
     * (non-Javadoc)
     * @see com.edooschool.oral.arithmetic.processor.WechatProcessor#requestAccessToken()
     */
    @Cacheable(value = CacheKeys.WechatCache.ACCESS_TOKEN)
    public Token requestAccessToken() {
        
        String url = StringUtils.connect(this.host, "/wechat/access-token");
        
        HttpResult httpResult = wechatRao.requestAccessToken(url);
        
        if(httpResult.isValid()) {
            
            String accessToken = (String) httpResult.get("access_token");
            long expire = (Long) httpResult.get("expire");
            
            return new Token(accessToken, expire);
        }
        
        logger.error("#requestToken - request token faild with code[{}], error[{}]", httpResult.getCode(), httpResult.getMessage());
        throw BusinessException.newInstance(httpResult.getCode(), httpResult.getMessage());
    }

    /*
     * (non-Javadoc)
     * @see com.edooschool.oral.arithmetic.processor.WechatProcessor#generateJsConfig(java.lang.String)
     */
    public JsConfig generateJsConfig(String curl) {
        JsTicket jsTicket = this.requestJsTicket();  // this could be cached
        return new JsConfig(jsTicket.getAppid(), jsTicket.getTicket(), curl);
    }

    /**
     * 
     * @return
     */
    @Cacheable(CacheKeys.WechatCache.JS_TICKET)
    protected JsTicket requestJsTicket() {
        
        String url = StringUtils.connect(this.host, "/openapi/wechat/js-ticket");
        
        HttpResult httpResult = wechatRao.requestJsTicket(url);
        
        if(httpResult.isValid()) {
            
            String appid = (String) httpResult.get("appid");
            String ticket = (String) httpResult.get("ticket");
            
            return new JsTicket(appid, ticket);
        }
        
        logger.error("#requestJsTicket - js ticket token faild with code[{}], error[{}]", httpResult.getCode(), httpResult.getMessage());
        throw BusinessException.newInstance(httpResult.getCode(), httpResult.getMessage());
    }

    /*
     * (non-Javadoc)
     * @see com.edooschool.oral.arithmetic.processor.WechatProcessor#generateMediaUrl(java.lang.String)
     */
    public String generateMediaUrl(String mediaId) {
        
        // get wechat global token
        Token token = this.requestAccessToken();
        logger.trace("#generateMediaUrl - get access token[{}]", token.getAccessToken());
        
        // generate fetch url
        return StringUtils.connect(Wechat.MediaUrl.MEDIA,  "?access_token=", token.getAccessToken(), "&media_id=", mediaId);
    }
    
    /*
     * (non-Javadoc)
     * @see com.edooschool.oral.arithmetic.processor.WechatProcessor#login(java.lang.String)
     */
    public WebAuthLogin login(String uuid) {
        
        String url = StringUtils.connect(this.host, "/wechat/web-auth/login");
        
        HttpResult httpResult = wechatRao.login(url, uuid);
        
        logger.info("##########################------loginResult------- [{}]", httpResult.getResponseText());
        
        if(httpResult.isValid()) {
            
            WebAuthLogin login = JsonUtils.parse(JsonUtils.toJson(httpResult.get("web_auth_login")), WebAuthLogin.class);
            return login;
        }
        
        throw BusinessException.newInstance(httpResult.getCode(), httpResult.getMessage());
    }
}
